#include <pcap.h>
#include <iostream>
#include <fstream>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h> // 引入 sleep 函数

// 处理捕获的数据包
void packetHandler(u_char *userData, const struct pcap_pkthdr* pkthdr, const u_char* packet) {
    std::ofstream &logFile = *(std::ofstream*)userData;
    struct ip* ipHeader = (struct ip*)(packet + 14); // 14 字节以太网头部

    char sourceIp[INET_ADDRSTRLEN];
    char destIp[INET_ADDRSTRLEN];

    inet_ntop(AF_INET, &(ipHeader->ip_src), sourceIp, INET_ADDRSTRLEN);
    inet_ntop(AF_INET, &(ipHeader->ip_dst), destIp, INET_ADDRSTRLEN);

    // 输出到控制台
    std::cout << "版本: " << (unsigned int)ipHeader->ip_v << std::endl;
    std::cout << "头部长度: " << (unsigned int)ipHeader->ip_hl << std::endl;
    std::cout << "服务类型: " << (unsigned int)ipHeader->ip_tos << std::endl;
    std::cout << "总长度: " << ntohs(ipHeader->ip_len) << std::endl;
    std::cout << "标识: " << ntohs(ipHeader->ip_id) << std::endl;
    std::cout << "标志: " << (unsigned int)(ntohs(ipHeader->ip_off) >> 13) << std::endl;
    std::cout << "片偏移: " << (ntohs(ipHeader->ip_off) & 0x1FFF) << std::endl;
    std::cout << "生存时间: " << (unsigned int)ipHeader->ip_ttl << std::endl;
    std::cout << "协议: " << (unsigned int)ipHeader->ip_p << std::endl;
    std::cout << "头部校验和: " << ntohs(ipHeader->ip_sum) << std::endl;
    std::cout << "源IP地址: " << sourceIp << std::endl;
    std::cout << "目标IP地址: " << destIp << std::endl;
    std::cout << std::endl;

    // 输出到日志文件
    logFile << "版本: " << (unsigned int)ipHeader->ip_v << std::endl;
    logFile << "头部长度: " << (unsigned int)ipHeader->ip_hl << std::endl;
    logFile << "服务类型: " << (unsigned int)ipHeader->ip_tos << std::endl;
    logFile << "总长度: " << ntohs(ipHeader->ip_len) << std::endl;
    logFile << "标识: " << ntohs(ipHeader->ip_id) << std::endl;
    logFile << "标志: " << (unsigned int)(ntohs(ipHeader->ip_off) >> 13) << std::endl;
    logFile << "片偏移: " << (ntohs(ipHeader->ip_off) & 0x1FFF) << std::endl;
    logFile << "生存时间: " << (unsigned int)ipHeader->ip_ttl << std::endl;
    logFile << "协议: " << (unsigned int)ipHeader->ip_p << std::endl;
    logFile << "头部校验和: " << ntohs(ipHeader->ip_sum) << std::endl;
    logFile << "源IP地址: " << sourceIp << std::endl;
    logFile << "目标IP地址: " << destIp << std::endl;
    logFile << std::endl;
}

int main() {
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t *descr = pcap_open_live("eth0", BUFSIZ, 1, 1000, errbuf); // 打开网络接口进行数据包捕获

    if (descr == nullptr) {
        std::cerr << "pcap_open_live() 失败: " << errbuf << std::endl;
        return 1;
    }

    std::ofstream logFile("packet_log.txt");

    if (!logFile.is_open()) {
        std::cerr << "无法打开日志文件." << std::endl;
        return 1;
    }

    sleep(1); // 程序运行1秒后开始抓包

    for (;;) {
        pcap_dispatch(descr, 1, packetHandler, (u_char*)&logFile); // 每次抓一个包
        sleep(1); // 每隔一秒抓一次
    }

    pcap_close(descr); // 结束捕获
    logFile.close();

    return 0;
}